#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <sys/time.h>

const char* level[] = {
  "INFO",
  "WARNING",
  "ERROR",
  "FATAL",
  "DEBUG"
};

enum ErrorLevel{
  INFO = 0,
  WARING,
  ERROR,
  FATAL,
  DEBUG
};

#define TIME_LEN 20

class LogTime{
  public:
    static int64_t GetTimeStamp(){
      timeval tv;
      gettimeofday(&tv, nullptr);
      return tv.tv_sec;
    }

    static void GetTimeStamp(std::string& time_stamp){
      time_t now;
      time(&now);
      tm* tp = localtime(&now);
      char tmp[TIME_LEN] = {0};
      snprintf(tmp, TIME_LEN, "%04d/%02d/%02d-%02d:%02d:%02d",
          tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec);
      time_stamp.assign(tmp, TIME_LEN);
    }
};

bool IsError(int ret, ErrorLevel lev = INFO){
  if(ret != 0){
    std::cout << "[" << level[lev] << "]" << std::endl;
    std::string time_stamp;
    LogTime::GetTimeStamp(time_stamp);
    std::cout << time_stamp << std::endl;
    printf("%s\n", strerror(ret));
    return true;
  }
  return false;
}

bool Perror(int ret, const char* op, ErrorLevel lev = INFO){
  if(ret < 0){
    std::cout << "[" << level[lev] << "]" << std::endl;
    std::string time_stamp;
    LogTime::GetTimeStamp(time_stamp);
    std::cout << time_stamp << std::endl;
    perror(op);
    return true;
  }
  return false;
}

#define LOG(format, ...) printf("FILE:%s, LINE:%d. " format "\n", __FILE__, __LINE__, ##__VA_ARGS__);
